bitkeeper revision 1.803 (4056f51d2UjBnn9uwzC9Vu3LspnUCg)
authormwilli2@equilibrium.research.intel-research.net <mwilli2@equilibrium.research.intel-research.net>
Tue, 16 Mar 2004 12:37:49 +0000 (12:37 +0000)
committermwilli2@equilibrium.research.intel-research.net <mwilli2@equilibrium.research.intel-research.net>
Tue, 16 Mar 2004 12:37:49 +0000 (12:37 +0000)
Simple oops analyser for Xen crashes.

.rootkeys
tools/misc/xensymoops.py [new file with mode: 0755]

index 3e0cb1e20fdd8eea3a8ea6e7c28ea12bf66269f8..bd6f6241f3d714dfc40804dd86e49798b49f39b0 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
@@ -64,6 +64,7 @@
 3f8bcf29ulZIC9rC4wM70H_q4s6VPg tools/misc/xen_log.c
 3f13d81eQ9Vz-h-6RDGFkNR9CRP95g tools/misc/xen_nat_enable
 3f13d81e6Z6806ihYYUw8GVKNkYnuw tools/misc/xen_nat_enable.README
+4056f5155QYZdsk-1fLdjsZPFTnlhg tools/misc/xensymoops.py
 4022a73cEKvrYe_DVZW2JlAxobg9wg tools/nsplitd/Makefile
 4022a73cKms4Oq030x2JBzUB426lAQ tools/nsplitd/nsplitd.c
 3fbca441SjQr8vJwTQIgH1laysaWog tools/xc/Makefile
diff --git a/tools/misc/xensymoops.py b/tools/misc/xensymoops.py
new file mode 100755 (executable)
index 0000000..835d187
--- /dev/null
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+# An oops analyser for Xen
+# Usage: xensymoops path-to-xen.s < oops-message
+
+# There's probably some more features that could go in here but this
+# is sufficient to analyse most errors in my code ;-)
+
+# by Mark Williamson (C) 2004 Intel Research Cambridge
+
+import re, sys
+
+def read_oops():
+    """Process an oops message on stdin and return (eip_addr, stack_addrs)
+
+    eip_addr is the location of EIP at the point of the crash.
+    stack_addrs is a dictionary mapping potential code addresses in the stack
+      to their order in the stack trace.
+    """
+    stackaddr_ptn = "\[([a-z,0-9]*)\]"
+    stackaddr_re  = re.compile(stackaddr_ptn)
+
+    eip_ptn = ".*EIP:.*<([a-z,0-9]*)>.*"
+    eip_re  = re.compile(eip_ptn)
+
+    matches = 0
+    stack_addresses = {}
+    eip_addr = "Not known"
+
+    while True:
+        line = sys.stdin.readline()
+        if not line: break
+
+        m = eip_re.match(line)
+        if m: eip_addr = m.group(1)
+        
+        m = stackaddr_re.findall(line)
+    
+        for i in m:
+            stack_addresses[i] = matches
+            matches += 1
+
+    return (eip_addr, stack_addresses)
+
+def usage():
+    print >> sys.stderr, """Usage: %s path-to-asm < oops-msg
+    The oops message should be fed to the standard input.  The
+    command-line argument specifies the path to the Xen assembly dump
+    produced by \"make debug\".  The location of EIP and the backtrace
+    will be output to standard output.
+    """ % sys.argv[0]
+    sys.exit()
+
+##### main
+
+if len(sys.argv) != 2:
+    usage()
+
+# get address of EIP and the potential code addresses from the stack
+(eip_addr, stk_addrs) = read_oops()
+
+# open Xen disassembly
+asm_file = open(sys.argv[1])
+
+# regexp to match addresses of code lines in the objdump
+addr_ptn = "([a-z,0-9]*):"
+addr_re  = re.compile(addr_ptn)
+
+# regexp to match the start of functions in the objdump
+func_ptn = "(.*<[\S]*>):"
+func_re  = re.compile(func_ptn)
+
+func = "<No function>" # holds the name of the current function being scanned
+
+eip_func = "<No function>" # name of the function EIP was in
+
+# list of (position in original backtrace, code address, function) tuples
+# describing all the potential code addresses we identified in the backtrace
+# whose addresses we also located in the objdump output
+backtrace = []
+
+while True:
+    line = asm_file.readline()
+    if not line: break
+
+    # if we've read the start of the function, record the name and address
+    fm = func_re.match(line)
+    if fm:
+        func = fm.group(1)
+        continue
+
+    # try match the address at the start of the line
+    m = addr_re.match(line)
+    if not m: continue
+
+    # we're on a code line...
+
+    address = m.group(1)
+
+    # if this address was seen as a potential code address in the backtrace then
+    # record it in the backtrace list
+    if stk_addrs.has_key(address):
+        backtrace.append((stk_addrs[address], address, func))
+
+    # if this was the address that EIP...
+    if address == eip_addr:
+        eip_func = func
+
+
+print "EIP %s in function %s" % (eip_addr, eip_func)
+print "Backtrace:"
+
+# sorting will order primarily by the first element of each tuple,
+# i.e. the order in the original oops
+backtrace.sort()
+
+for (i, a, f) in backtrace:
+    print "%s in function %s" % ( a, f )